package xin.marcher.module.diplomacy.api.impl;

import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import xin.marcher.module.common.core.JsonResult;
import xin.marcher.module.common.exception.ProductErrorCodeEnum;
import xin.marcher.module.diplomacy.api.ProductLabelApi;
import xin.marcher.module.diplomacy.converter.LabelConverter;
import xin.marcher.module.diplomacy.domain.bo.FrontCategoryLabelRelationBO;
import xin.marcher.module.diplomacy.domain.bo.LabelBO;
import xin.marcher.module.diplomacy.domain.bo.ProductLabelRelationBO;
import xin.marcher.module.diplomacy.domain.dto.LabelDTO;
import xin.marcher.module.diplomacy.domain.dto.ProductLabelRelationDetailDTO;
import xin.marcher.module.diplomacy.domain.query.FrontCategoryLabelQuery;
import xin.marcher.module.diplomacy.domain.query.LabelProductQuery;
import xin.marcher.module.diplomacy.manager.custom.cache.FrontCategoryLabelRelationCache;
import xin.marcher.module.diplomacy.manager.custom.cache.LabelCache;
import xin.marcher.module.diplomacy.manager.custom.cache.ProductLabelRelationCache;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品标签接口
 */
@Slf4j
@DubboService(version = "1.0.0", interfaceClass = ProductLabelApi.class, retries = 0)
public class ProductLabelApiImpl implements ProductLabelApi {

    @Resource
    private FrontCategoryLabelRelationCache frontCategoryLabelRelationCache;

    @Resource
    private LabelCache labelCache;

    @Resource
    private ProductLabelRelationCache productLabelRelationCache;

    @Resource
    private LabelConverter labelConverter;

    /**
     * 根据前台末级类目id查询要展示的标签接口
     */
    @Override
    public JsonResult<List<LabelDTO>> listLabels(FrontCategoryLabelQuery query) {
        // 入参校验
        if (Objects.isNull(query) || Objects.isNull(query.getFrontCategoryId())) {
            return JsonResult.buildError(ProductErrorCodeEnum.PARAM_ERROR.getErrorCode(), ProductErrorCodeEnum.PARAM_ERROR.getErrorMsg());
        }

        // 查询关系
        List<String> frontCategoryIdList = Collections.singletonList(String.valueOf(query.getFrontCategoryId()));
        Optional<List<FrontCategoryLabelRelationBO>> optional = frontCategoryLabelRelationCache.listRedisStringData(true, frontCategoryIdList);
        if (!optional.isPresent()) {
            return JsonResult.buildSuccess();
        }

        // 查询标签
        List<String> labelIds = optional.get().stream().map(FrontCategoryLabelRelationBO::getLabelId)
                .map(String::valueOf).collect(Collectors.toList());
        Optional<List<LabelBO>> labelBOS = labelCache.listRedisStringData(true, labelIds);
        if (!labelBOS.isPresent()) {
            return JsonResult.buildSuccess();
        }

        List<LabelDTO> labelDTOS = labelConverter.converterLabelList(labelBOS.get());
        return JsonResult.buildSuccess(labelDTOS);
    }

    /**
     * 根据多个标签id查询对应商品接口
     */
    @Override
    public JsonResult<List<ProductLabelRelationDetailDTO>> listProducts(LabelProductQuery query) {
        // 入参校验
        if (Objects.isNull(query) || CollectionUtil.isEmpty(query.getLabelIds())) {
            return JsonResult.buildError(ProductErrorCodeEnum.PARAM_ERROR.getErrorCode(), ProductErrorCodeEnum.PARAM_ERROR.getErrorMsg());
        }

        List<String> labelIds = query.getLabelIds().stream().map(String::valueOf).collect(Collectors.toList());
        Optional<List<ProductLabelRelationBO>> productLabelRelationBOS = productLabelRelationCache.listRedisStringData(true, labelIds);
        if (!productLabelRelationBOS.isPresent()) {
            return JsonResult.buildSuccess();
        }

        Map<Long, List<ProductLabelRelationBO>> map = productLabelRelationBOS.get().stream()
                .collect(Collectors.groupingBy(ProductLabelRelationBO::getLabelId));

        List<ProductLabelRelationDetailDTO> list = new ArrayList<>();
        map.forEach((k, v) -> {
            ProductLabelRelationDetailDTO dto = new ProductLabelRelationDetailDTO();
            dto.setLabelId(k);
            List<ProductLabelRelationDetailDTO.Participant> participants = v.stream()
                    .map(e -> new ProductLabelRelationDetailDTO.Participant(e.getParticipantId(), e.getParticipantType()))
                    .collect(Collectors.toList());
            dto.setParticipants(participants);
            list.add(dto);
        });

        return JsonResult.buildSuccess(list);
    }

}
